home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / DCLAP 6d / dclap6d / network / entrez / client / netlib.c < prev    next >
Text File  |  1996-07-05  |  24KB  |  839 lines

  1. /*   netlib.c
  2. * ===========================================================================
  3. *
  4. *                            PUBLIC DOMAIN NOTICE                          
  5. *               National Center for Biotechnology Information
  6. *                                                                          
  7. *  This software/database is a "United States Government Work" under the   
  8. *  terms of the United States Copyright Act.  It was written as part of    
  9. *  the author's official duties as a United States Government employee and 
  10. *  thus cannot be copyrighted.  This software/database is freely available 
  11. *  to the public for use. The National Library of Medicine and the U.S.    
  12. *  Government have not placed any restriction on its use or reproduction.  
  13. *                                                                          
  14. *  Although all reasonable efforts have been taken to ensure the accuracy  
  15. *  and reliability of the software and data, the NLM and the U.S.          
  16. *  Government do not and cannot warrant the performance or results that    
  17. *  may be obtained by using this software or data. The NLM and the U.S.    
  18. *  Government disclaim all warranties, express or implied, including       
  19. *  warranties of performance, merchantability or fitness for any particular
  20. *  purpose.                                                                
  21. *                                                                          
  22. *  Please cite the author in any work or product based on this material.   
  23. *
  24. * ===========================================================================
  25. *
  26. * File Name:  netlib.c
  27. *
  28. * Author:  Epstein
  29. *
  30. * Version Creation Date:   06/05/92
  31. *
  32. * $Revision: 4.0 $
  33. *
  34. * File Description: 
  35. *       miscellaneous library for network Entrez
  36. *
  37. * Modifications:  
  38. * --------------------------------------------------------------------------
  39. * Date     Name        Description of modification
  40. * -------  ----------  -----------------------------------------------------
  41. *
  42. * ==========================================================================
  43. *
  44. *
  45. * RCS Modification History:
  46. * $Log: netlib.c,v $
  47.  * Revision 4.0  1995/07/26  13:54:59  ostell
  48.  * force revision to 4.0
  49.  *
  50.  * Revision 1.22  1995/05/17  17:53:17  epstein
  51.  * add RCS log revision history
  52.  *
  53. */
  54.  
  55. #include <ncbi.h>
  56. #include <asn.h>
  57. #include <accentr.h>
  58. #include <cdconfig.h>
  59. #include <ncbinet.h>
  60. #include <netentr.h>
  61. #include <netpriv.h>
  62. #include <objmedli.h>
  63. #include <objsset.h>
  64. #include <objloc.h>
  65. #include <objneten.h>
  66.  
  67. #define STAT_CHUNK 32
  68.  
  69. static Boolean loaded = FALSE;
  70.  
  71. static NetStatPtr PNTR statVector = NULL;
  72. static Int2 numStats = 0;
  73. static Boolean statsDisabled = FALSE;
  74. static Int2 maxCurStats;
  75. static Boolean reallyFinal = TRUE;
  76.  
  77. static int num_attached = 0;
  78. static char lastDispatcher[60];
  79. static NI_HandPtr lastEntrezServ = NULL;
  80. static CharPtr statsPtr = NULL;
  81. static NI_DispatcherPtr dispatcher = NULL;
  82.  
  83. static AsnTypePtr ENTREZ_TERM_LIST = NULL;
  84. static AsnTypePtr ENTREZ_TERM_LIST_E = NULL;
  85. static AsnTypePtr ENTREZ_TERM_LIST_E_operator = NULL;
  86. static AsnTypePtr ENTREZ_TERM_LIST_E_sp_operand = NULL;
  87. static AsnTypePtr ENTREZ_TERM_LIST_E_tot_operand = NULL;
  88. static AsnTypePtr ENTREZ_TERM_RESP = NULL;
  89. static AsnTypePtr ENTREZ_TERM_RESP_first_page = NULL;
  90. static AsnTypePtr ENTREZ_TERM_RESP_info = NULL;
  91. static AsnTypePtr ENTREZ_TERM_RESP_info_E = NULL;
  92. static AsnTypePtr ENTREZ_TERM_RESP_num_terms = NULL;
  93. static AsnTypePtr ENTREZ_TERM_RESP_pages_read = NULL;
  94. static AsnTypePtr SPECIAL_OPERAND_fld = NULL;
  95. static AsnTypePtr SPECIAL_OPERAND_term = NULL;
  96. static AsnTypePtr SPECIAL_OPERAND_type = NULL;
  97. static AsnTypePtr TOTAL_OPERAND_fld = NULL;
  98. static AsnTypePtr TOTAL_OPERAND_term = NULL;
  99. static AsnTypePtr TOTAL_OPERAND_type = NULL;
  100.  
  101. static void appendStats PROTO((CharPtr s));
  102. static Int2 NEAR statCompare PROTO((NetStatPtr s1, NetStatPtr s2));
  103. static void NEAR FreeNetStats PROTO((void));
  104. static Boolean SwapOutNet PROTO ((VoidPtr med));
  105.  
  106.  
  107. static void NEAR FindAsnType (AsnTypePtr PNTR atp, AsnModulePtr amp, CharPtr str)
  108.  
  109. {
  110.   if (atp != NULL && (*atp) == NULL) {
  111.     *atp = AsnTypeFind (amp, str);
  112.   }
  113. }
  114.  
  115. static Boolean InitLoad()
  116. {
  117.     AsnModulePtr amp;
  118.     static Boolean loaded = FALSE;
  119.  
  120.     if (loaded)
  121.     return TRUE;
  122.     if (! NetEntAsnLoad() )
  123.         return FALSE;
  124.     amp = AsnAllModPtr();
  125.  
  126.     FindAsnType(&ENTREZ_TERM_LIST, amp, "Entrez-term-list");
  127.     FindAsnType(&ENTREZ_TERM_LIST_E, amp, "Entrez-term-list.E");
  128.     FindAsnType(&ENTREZ_TERM_LIST_E_operator, amp, "Entrez-term-list.E.operator");
  129.     FindAsnType(&ENTREZ_TERM_LIST_E_sp_operand, amp, "Entrez-term-list.E.sp-operand");
  130.     FindAsnType(&ENTREZ_TERM_LIST_E_tot_operand, amp, "Entrez-term-list.E.tot-operand");
  131.     FindAsnType(&ENTREZ_TERM_RESP, amp, "Entrez-term-resp");
  132.     FindAsnType(&ENTREZ_TERM_RESP_first_page, amp, "Entrez-term-resp.first-page");
  133.     FindAsnType(&ENTREZ_TERM_RESP_info, amp, "Entrez-term-resp.info");
  134.     FindAsnType(&ENTREZ_TERM_RESP_info_E, amp, "Entrez-term-resp.info.E");
  135.     FindAsnType(&ENTREZ_TERM_RESP_num_terms, amp, "Entrez-term-resp.num-terms");
  136.     FindAsnType(&ENTREZ_TERM_RESP_pages_read, amp, "Entrez-term-resp.pages-read");
  137.     FindAsnType(&SPECIAL_OPERAND_fld, amp, "Special-operand.fld");
  138.     FindAsnType(&SPECIAL_OPERAND_term, amp, "Special-operand.term");
  139.     FindAsnType(&SPECIAL_OPERAND_type, amp, "Special-operand.type");
  140.     FindAsnType(&TOTAL_OPERAND_fld, amp, "Total-operand.fld");
  141.     FindAsnType(&TOTAL_OPERAND_term, amp, "Total-operand.term");
  142.     FindAsnType(&TOTAL_OPERAND_type, amp, "Total-operand.type");
  143.  
  144.     loaded = TRUE;
  145.     return TRUE;
  146. }
  147.  
  148.  
  149. TermRespPtr CDECL TermRespNew(void)
  150. {
  151.     TermRespPtr p;
  152.  
  153.     p = (TermRespPtr) MemNew(sizeof(TermResp));
  154.     p->num_terms = 0;
  155.     if (p != NULL)
  156.     {
  157.         p->termresp = NULL;
  158.     }
  159.     return p;
  160. }
  161.  
  162. TermRespPtr CDECL
  163. TermRespFree(TermRespPtr p)
  164. {
  165.     if (p == NULL)
  166.         return NULL;
  167.     if (p->termresp != NULL)
  168.     {
  169.         if (p->termresp->term != NULL)
  170.             MemFree(p->termresp->term);
  171.         MemFree (p->termresp);
  172.     }
  173.     return ((TermRespPtr) MemFree (p));
  174. }
  175.  
  176. TermRespPtr CDECL TermRespAsnRead (AsnIoPtr aip, AsnTypePtr orig)
  177. {
  178.     DataVal av;
  179.     AsnTypePtr atp;
  180.     int i;
  181.     TermRespPtr tp;
  182.     TermPageInfoPtr tpi;
  183.     AsnModulePtr amp;
  184.  
  185.     amp = AsnAllModPtr();
  186.  
  187.     if (aip == NULL)
  188.         return NULL;
  189.  
  190.     if (orig == NULL)
  191.         atp = AsnReadId(aip, amp, ENTREZ_TERM_RESP);
  192.     else
  193.         atp = AsnLinkType(orig, ENTREZ_TERM_RESP); /* link in local tree */
  194.  
  195.     if (atp == NULL)
  196.         return NULL;
  197.  
  198.     tp = TermRespNew();
  199.  
  200.     if (tp == NULL)
  201.         goto erret;
  202.  
  203.     if (AsnReadVal(aip, atp, NULL) <= 0) /* read the start struct */
  204.         goto erret;
  205.     if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_TERM_RESP_num_terms)
  206.         goto erret;
  207.     if (AsnReadVal(aip, atp, &av) < 0)
  208.         goto erret;
  209.     tp->num_terms = av.intvalue;
  210.     tp->first_page = -1;
  211.  
  212.     if ((atp = AsnReadId(aip, amp, atp)) == ENTREZ_TERM_RESP_first_page)
  213.     { /* optional */
  214.         if (AsnReadVal(aip, atp, &av) < 0)
  215.             goto erret;
  216.         tp->first_page = av.intvalue;
  217.         atp = AsnReadId(aip, amp, atp);
  218.     }
  219.  
  220.     if (atp != ENTREZ_TERM_RESP_pages_read)
  221.         goto erret;
  222.     if (AsnReadVal(aip, atp, &av) <= 0)
  223.         goto erret;
  224.     tp->num_pages_read = av.intvalue;
  225.  
  226.     if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_TERM_RESP_info)
  227.         goto erret;
  228.     if (AsnReadVal(aip, atp, NULL) <= 0)
  229.         goto erret;
  230.     tp->termresp = MemNew(sizeof(struct termresp) * (size_t) tp->num_terms);
  231.     for (i = 0; i < tp->num_terms; i++)
  232.     {
  233.         if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_TERM_RESP_info_E)
  234.             goto erret;
  235.         if ((tpi = TermPageInfoAsnRead(aip, atp)) == NULL)
  236.             goto erret;
  237.         tp->termresp[i].special_count = tpi->spec_count;
  238.         tp->termresp[i].total_count = tpi->tot_count;
  239.         tp->termresp[i].term = tpi->term;
  240.         tpi->term = NULL; /* for clean free */
  241.         TermPageInfoFree (tpi);
  242.     }
  243.  
  244.     if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_TERM_RESP_info)
  245.         goto erret;
  246.     if (AsnReadVal(aip, atp, NULL) < 0)
  247.         goto erret;
  248.  
  249.     atp = AsnReadId(aip, amp, atp);
  250.     if (orig == NULL)
  251.     {
  252.         if (atp != ENTREZ_TERM_RESP)
  253.             goto erret;
  254.     }
  255.     else { /* check for "close struct" associated with "orig" */
  256.         if (atp != orig)
  257.             goto erret;
  258.     }
  259.  
  260.     if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
  261.         goto erret;
  262.     
  263. ret:
  264.     AsnUnlinkType(orig);
  265.     return tp;
  266.  
  267. erret:
  268.     tp = TermRespFree (tp);
  269.     goto ret;
  270. }
  271.  
  272. Boolean CDECL
  273. BoolExprAsnWrite(ValNodePtr elst, AsnIoPtr aip, AsnTypePtr orig)
  274. {
  275.     DataVal av;
  276.     static int n = 0;
  277.     TermDataPtr tp;
  278.     Boolean retval = FALSE;
  279.     AsnTypePtr atp;
  280.  
  281.     if (aip == NULL)
  282.         return FALSE;
  283.     atp = AsnLinkType(orig, ENTREZ_TERM_LIST); /* link local tree */
  284.  
  285.     if (atp == NULL)
  286.         return FALSE;
  287.  
  288.     if (elst == NULL)
  289.     {
  290.         AsnNullValueMsg(aip, atp);
  291.         goto erret;
  292.     }
  293.  
  294.     if (! AsnStartStruct(aip, atp))
  295.         goto erret;
  296.  
  297.     for (; elst != NULL; elst = elst->next)
  298.     {
  299.         AsnWrite (aip, ENTREZ_TERM_LIST_E, NULL);
  300.         switch (elst->choice) {
  301.         case SPECIALTERM:
  302.             tp = (TermDataPtr) elst->data.ptrvalue;
  303.  
  304.             AsnStartStruct (aip, ENTREZ_TERM_LIST_E_sp_operand);
  305.             av.ptrvalue = tp->term;
  306.             AsnWrite (aip, SPECIAL_OPERAND_term, &av);
  307.             av.intvalue = tp->field;
  308.             AsnWrite (aip, SPECIAL_OPERAND_fld, &av);
  309.             av.intvalue = tp->type;
  310.             AsnWrite (aip, SPECIAL_OPERAND_type, &av);
  311.             AsnEndStruct (aip, ENTREZ_TERM_LIST_E_sp_operand);
  312.             break;
  313.         case TOTALTERM:
  314.             tp = (TermDataPtr) elst->data.ptrvalue;
  315.  
  316.             AsnStartStruct (aip, ENTREZ_TERM_LIST_E_tot_operand);
  317.             av.ptrvalue = tp->term;
  318.             AsnWrite (aip, TOTAL_OPERAND_term, &av);
  319.             av.intvalue = tp->field;
  320.             AsnWrite (aip, TOTAL_OPERAND_fld, &av);
  321.             av.intvalue = tp->type;
  322.             AsnWrite (aip, TOTAL_OPERAND_type, &av);
  323.             AsnEndStruct (aip, ENTREZ_TERM_LIST_E_tot_operand);
  324.             break;
  325.         case LPAREN:
  326.         case RPAREN:
  327.         case ANDSYMBL:
  328.         case ORSYMBL:
  329.         case BUTNOTSYMBL:
  330.             av.intvalue = elst->choice;
  331.             AsnWrite (aip, ENTREZ_TERM_LIST_E_operator, &av);
  332.             break;
  333.         default:
  334.             break;
  335.         }
  336.     }
  337.  
  338.  
  339.     if (! AsnEndStruct(aip, atp))
  340.         goto erret;
  341.  
  342.     retval = TRUE;
  343.  
  344. erret:
  345.     AsnUnlinkType(orig);
  346.     return retval;
  347. }
  348.  
  349. ValNodePtr CDECL
  350. BoolExprAsnRead(AsnIoPtr aip, AsnTypePtr orig)
  351. {
  352.     ValNodePtr anp = NULL;
  353.     ValNodePtr head = NULL;
  354.     DataVal av;
  355.     TermDataPtr tp;
  356.     AsnTypePtr atp;
  357.     AsnTypePtr startsym;
  358.     AsnModulePtr amp;
  359.  
  360.     InitLoad();
  361.     amp = AsnAllModPtr();
  362.  
  363.     if (aip == NULL)
  364.         return NULL;
  365.  
  366.     if (orig == NULL)
  367.         atp = AsnReadId(aip, amp, ENTREZ_TERM_LIST);
  368.     else
  369.         atp = AsnLinkType(orig, ENTREZ_TERM_LIST); /* link in local tree */
  370.  
  371.     if (atp == NULL)
  372.         return NULL;
  373.  
  374.     if (AsnReadVal(aip, atp, NULL) < 0)
  375.         goto erret;
  376.  
  377.     while ((atp = AsnReadId(aip, amp, atp)) == ENTREZ_TERM_LIST_E)
  378.     {
  379.         if (AsnReadVal(aip, atp, NULL) < 0)
  380.             goto erret;
  381.  
  382.         atp = AsnReadId(aip, amp, atp);
  383.  
  384.         if (atp == ENTREZ_TERM_LIST_E_sp_operand ||
  385.             atp == ENTREZ_TERM_LIST_E_tot_operand)
  386.         {
  387.             startsym = atp; /* save this, to be able to find "close" sym */
  388.  
  389.             anp = ValNodeNew(anp);
  390.             if (head == NULL) /* keep track of head of list */
  391.                 head = anp;
  392.  
  393.             if (atp == ENTREZ_TERM_LIST_E_sp_operand)
  394.                 anp->choice = SPECIALTERM;
  395.             else
  396.                 anp->choice = TOTALTERM;
  397.  
  398.             if (AsnReadVal(aip, atp, NULL) < 0)
  399.                 goto erret;
  400.  
  401.             tp = (TermDataPtr) MemNew(sizeof(TermData));
  402.             anp->data.ptrvalue = (Pointer) tp;
  403.  
  404.             if (tp == NULL)
  405.                 goto erret;
  406.         
  407.             if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* term */
  408.                 goto erret;
  409.             if (AsnReadVal(aip, atp, &av) < 0)
  410.                 goto erret;
  411.             tp->term = av.ptrvalue;
  412.  
  413.             if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* fld */
  414.                 goto erret;
  415.             if (AsnReadVal(aip, atp, &av) < 0)
  416.                 goto erret;
  417.             tp->field = av.intvalue;
  418.  
  419.             if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* type */
  420.                 goto erret;
  421.             if (AsnReadVal(aip, atp, &av) < 0)
  422.                 goto erret;
  423.             tp->type = av.intvalue;
  424.  
  425.             if ((atp = AsnReadId(aip, amp, atp)) != startsym)
  426.                 goto erret;
  427.             if (AsnReadVal(aip, atp, NULL) < 0)
  428.                 goto erret;
  429.         }
  430.         else
  431.         if (atp == ENTREZ_TERM_LIST_E_operator)
  432.         {
  433.             if (AsnReadVal(aip, atp, &av) < 0)
  434.                 goto erret;
  435.             anp = ValNodeNew(anp);
  436.             if (head == NULL) /* keep track of head of list */
  437.                 head = anp;
  438.             anp->choice = av.intvalue;
  439.         }
  440.         else
  441.             goto erret;
  442.     }
  443.  
  444.     if (orig == NULL)
  445.     {
  446.         if (atp != ENTREZ_TERM_LIST)
  447.             goto erret;
  448.     }
  449.     else {
  450.         if (atp != orig)
  451.             goto erret;
  452.     }
  453.  
  454.     /* discard last value */
  455.     if (AsnReadVal(aip, atp, NULL) < 0)
  456.         goto erret;
  457.  
  458.     AsnUnlinkType(orig);
  459.     return head;
  460.  
  461. erret:
  462.     ValNodeFree (head);
  463.     return NULL;
  464. }
  465.  
  466. static void appendStats(CharPtr s)
  467. {
  468.     if (s != NULL)
  469.     {
  470.         StrCat(statsPtr, "    ");
  471.         StrCat(statsPtr, s);
  472.         StrCat(statsPtr, "\n");
  473.         statsPtr += StringLen(statsPtr);
  474.     }
  475. }
  476.  
  477. extern void GetClientInfo (CharPtr buf)
  478. {
  479.     if (buf == NULL)
  480.         return;
  481.  
  482.     StrCpy(buf, "NETWORK ACCESS\n  Last Dispatcher Used: ");
  483.     StrCat(buf, lastDispatcher);
  484.     StrCat(buf, "\n");
  485.     if (dispatcher != NULL)
  486.     {
  487.         if (dispatcher->motd != NULL && dispatcher->motd[0] != NULLB)
  488.         {
  489.             StrCat(buf, "\n  ");
  490.             StrCat(buf, dispatcher->motd);
  491.             StrCat(buf, "\n");
  492.         }
  493.         if (dispatcher->adminInfo != NULL && dispatcher->adminInfo[0] != NULLB)
  494.         {
  495.             StrCat(buf, "\n  Your Network Entrez administrator is:\n    ");
  496.             StrCat(buf, dispatcher->adminInfo);
  497.         }
  498.     }
  499.     if (lastEntrezServ != NULL)
  500.     {
  501.         StrCat(buf, "\n  Entrez service currently connected to ");
  502.         StrCat(buf, lastEntrezServ->hostname);
  503.         StrCat(buf, " server\n");
  504.         if (NI_EncrAvailable())
  505.         {
  506.             if (lastEntrezServ->encryption != NULL)
  507.             {
  508.                 StrCat (buf, "  Encrypted session\n");
  509.             } else {
  510.                 StrCat (buf, "  Encryption available, but not in use\n");
  511.             }
  512.         }
  513.         statsPtr = &buf[StringLen(buf)];
  514.         DumpNetStats(SUBSYS_CLI_ENTREZ, appendStats);
  515.     }
  516. }
  517.  
  518. static Int2 NEAR statCompare (NetStatPtr s1, NetStatPtr s2)
  519. {
  520.     if (s1 == NULL || s2 == NULL)
  521.         return 0;
  522.     if (s1->subsys < s2->subsys)
  523.         return -1;
  524.     if (s1->subsys > s2->subsys)
  525.         return 1;
  526.     return (Int2) StrCmp(s1->label, s2->label);
  527. }
  528.     
  529. static void NEAR FreeNetStats (void)
  530. {
  531.     NetStatPtr PNTR statptr;
  532.     Int2 i;
  533.  
  534.     for (statptr = statVector, i = 0; i < numStats; i++, statptr++)
  535.     {
  536.         MemFree((*statptr)->label);
  537.         MemFree((*statptr));
  538.     }
  539.  
  540.     MemFree(statVector);
  541.     statVector = NULL;
  542.     numStats = 0;
  543.     statsDisabled = TRUE;
  544. }
  545.  
  546. void CDECL DumpNetStats (Int2 subsys, StatsCallBack callBack)
  547. {
  548.     char s[200];
  549.     int i;
  550.     NetStatPtr stat;
  551.     Boolean foundFirst = FALSE;
  552.     Boolean okSubsys;
  553.     Int4 total;
  554.     double mean;
  555.     double stdev;
  556.  
  557.     for (i = 0; i < numStats; i++)
  558.     {
  559.         stat = statVector[i];
  560.         if (stat == NULL)
  561.             continue;
  562.          
  563.         okSubsys = stat->subsys == subsys || subsys == 0;
  564.         if (!foundFirst)
  565.         {
  566.             if (okSubsys)
  567.                 foundFirst = TRUE;
  568.             else
  569.                 continue;
  570.         }
  571.         if (foundFirst && !okSubsys)
  572.             break;
  573.         total = (Int4) (stat->total + 0.5);
  574.  
  575.         switch (stat->flags) {
  576.         case STAT_MEAN :
  577.             StrCpy (s, "{");
  578.             StrCat (s, stat->label);
  579.             if (stat->n > 0)
  580.                 mean = stat->total / stat->n;
  581.             else
  582.                 mean = 0.0;
  583.             sprintf (&s[strlen(s)], "} total = %ld, mean = %f", (long) total,
  584.                      mean);
  585.             break;
  586.         case STAT_MEAN | STAT_STDEV :
  587.             StrCpy (s, "{");
  588.             StrCat (s, stat->label);
  589.             if (stat->n > 0)
  590.                 mean = stat->total / stat->n;
  591.             else
  592.                 mean = 0.0;
  593.             if (stat->n <= 1)
  594.                 stdev = 0.0;
  595.             else
  596.                 stdev = sqrt(stat->sum_of_squares / (stat->n - 1));
  597.             sprintf (&s[strlen(s)], "} total = %ld, mean = %f, stdev = %f",
  598.                      (long) total, mean, stdev);
  599.             break;
  600.         default :
  601.             StrCpy (s, stat->label);
  602.             sprintf (&s[strlen(s)], " = %ld", (long) total);
  603.             break;
  604.         }
  605.         callBack (s);
  606.     }
  607. }
  608.     
  609.  
  610. void CDECL LogNetStats (Int2 subsys, CharPtr label, Int4 dat,
  611.                          NetStatPtr PNTR statHandle, Int2 flags)
  612. {
  613.     Int2 l;
  614.     Int2 r;
  615.     Int2 k;
  616.     Int2 compValue;
  617.     NetStatPtr newStat;
  618.     NetStatPtr Stat;
  619.     double mean;
  620.     double tempterm;
  621.  
  622.     if (statsDisabled)
  623.         return;
  624.  
  625.     if (statHandle == NULL || label == NULL)
  626.         return;
  627.  
  628.     if (*statHandle == NULL)
  629.     {
  630.         newStat = (NetStatPtr) MemNew(sizeof(NetStat));
  631.         newStat->subsys = subsys;
  632.         newStat->label = StringSave(label);
  633.         newStat->total = 0;
  634.         newStat->n = 0;
  635.         newStat->flags = 0;
  636.         newStat->sum_of_squares = 0.0;
  637.         k = 0;
  638.         if (statVector != NULL)
  639.         {
  640.             l = 0;
  641.             r = numStats - 1;
  642.             compValue = statCompare(newStat, statVector[k]);
  643.             while ((l <= r) && compValue != 0)
  644.             {
  645.                 k = (l + r) / 2;
  646.                 if ((compValue = statCompare(newStat, statVector[k])) < 0)
  647.                     r = k - 1;
  648.                 else
  649.                     l = k + 1;
  650.             }
  651.             if (compValue == 0)
  652.             { /* match */
  653.                 *statHandle = statVector[k];
  654.                 MemFree(newStat->label);
  655.                 MemFree(newStat); /* not needed */
  656.             }
  657.             else {
  658.                 while (compValue > 0 && k < numStats)
  659.                 {
  660.                     k++;
  661.                     compValue = statCompare(newStat, statVector[k]);
  662.                 }
  663.             }
  664.         }
  665.  
  666.         if (*statHandle == NULL)
  667.         { /* not found previously */
  668.             if (statVector == NULL)
  669.             {
  670.                 if ((statVector = (NetStatPtr PNTR) MemNew(sizeof(NetStatPtr) *
  671.                      STAT_CHUNK)) == NULL)
  672.                 {
  673.                     MemFree(newStat->label);
  674.                     MemFree(newStat);
  675.                     return;
  676.                 }
  677.                 maxCurStats = STAT_CHUNK;
  678.             }
  679.  
  680.             /* re-allocate vector if necessary */
  681.             if (numStats >= maxCurStats - 1)
  682.             {
  683.                 maxCurStats += STAT_CHUNK;
  684.                 if ((statVector = (NetStatPtr PNTR) Realloc(statVector,
  685.                      sizeof(NetStatPtr) * maxCurStats)) == NULL)
  686.                 {
  687.                     MemFree(newStat->label);
  688.                     MemFree(newStat);
  689.                     return;
  690.                 }
  691.             }
  692.  
  693.             /* move everything else up */
  694.             for (r = numStats - 1; r >= k; r--)
  695.             {
  696.                 statVector[r+1] = statVector[r];
  697.             }
  698.             statVector[k] = newStat;
  699.             *statHandle = newStat;
  700.             numStats++;
  701.         }
  702.     }
  703.  
  704.     Stat = *statHandle;
  705.     Stat->n++;
  706.     Stat->total += dat;
  707.     Stat->flags |= flags;
  708.     mean = Stat->total / Stat->n;
  709.     tempterm = (mean - dat);
  710.     Stat->sum_of_squares += tempterm * tempterm;
  711. }
  712.  
  713. /*******************************************************************************
  714. *
  715. *    NetInit()
  716. *
  717. *    Connect to the network services dispatcher, unless already attached.
  718. *******************************************************************************/
  719.  
  720. Boolean NetInit(void)
  721. {
  722.     if (! InitLoad())
  723.     return FALSE;
  724.  
  725.     if (num_attached++ > 0)
  726.         return TRUE;
  727.  
  728.     /* if ( there are no network-media ) then */
  729.     if (ParseMedia(NULL, MEDIUM_NETWORK) == 0)
  730.     {
  731.         num_attached--;
  732.         return FALSE;
  733.     }
  734.  
  735.     if ((dispatcher = NI_GenericInit(NULL, NULL, TRUE, lastDispatcher, sizeof(lastDispatcher))) != NULL) {
  736.         return TRUE;
  737.     }
  738.  
  739.     num_attached--;
  740.     return FALSE;
  741. }
  742.  
  743.  
  744. /*******************************************************************************
  745. *
  746. *    NetInit()
  747. *
  748. *    Disconnect from the network services dispatcher, if this is the last
  749. *    service user which is detaching.
  750. *******************************************************************************/
  751.  
  752. Boolean CDECL NetFini(void)
  753. {
  754.     if (num_attached > 0)
  755.         num_attached--;
  756.  
  757.     if (num_attached == 0)
  758.     {
  759.         NI_EndServices (dispatcher);
  760.         if (reallyFinal)
  761.             FreeNetStats();
  762.     }
  763.  
  764.     return TRUE;
  765. }
  766.  
  767. Boolean CDECL ForceNetInit(void)
  768. {
  769.     Boolean retval;
  770.  
  771.     reallyFinal = FALSE;
  772.     num_attached = 0; /* force re-attempt to contact dispatcher */
  773.     retval =  NetInit();
  774.     reallyFinal = TRUE;
  775.  
  776.     return retval;
  777. }
  778.  
  779. NI_HandPtr NetServiceGet(CharPtr channel, CharPtr def_service,
  780.                          ConfCtlProc swapInProc, NI_HandPtr oldSessionHandle)
  781. {
  782.     MediaPtr media;
  783.     NetMediaInfoPtr nmi;
  784.     NI_HandPtr firstSessionHandle = NULL;
  785.     CharPtr param_section;
  786.  
  787.     /* coding-trick to make current media match type "channel" */
  788.     if (! SelectDataSource(channel, "MEDIA", NULL))
  789.     {
  790.         return NULL;
  791.     }
  792.  
  793.     do {
  794.         media = GetCurMedia();
  795.         if (media == NULL)
  796.             continue;
  797.         if (media->media_type != MEDIUM_NETWORK)
  798.             continue;
  799.         nmi = (NetMediaInfoPtr) media->media_info;
  800.  
  801.         /* if media is already initialized, only attempt to re-obtain service */
  802.         /* if this media matches the media which failed or timed-out          */
  803.         if (nmi != NULL && nmi->sessionHandle != oldSessionHandle)
  804.             continue;
  805.  
  806.         if (nmi != NULL)
  807.         { /* de-allocate old resources */
  808.             NI_ServiceDisconnect(nmi->sessionHandle);
  809.             nmi->sessionHandle = NULL;
  810.         }
  811.         else { /* allocate structure */
  812.             nmi = (NetMediaInfoPtr) MemNew(sizeof(NetMediaInfo));
  813.             media->media_info = (VoidPtr) nmi;
  814.         }
  815.         nmi->sessionHandle = NULL;
  816.  
  817.         media->swapOutMedia = SwapOutNet;
  818.         media->swapInMedia = swapInProc;
  819.  
  820.         param_section = media->media_alias;
  821.  
  822.         nmi->sessionHandle = NI_GenericGetService(dispatcher, NULL,
  823.                                                   param_section, def_service,
  824.                                                   TRUE);
  825.         if (firstSessionHandle == NULL)
  826.             firstSessionHandle = nmi->sessionHandle;
  827.     } while (SelectNextDataSource());
  828.  
  829.     lastEntrezServ = firstSessionHandle;
  830.  
  831.     return firstSessionHandle;
  832. }
  833.  
  834.  
  835. static Boolean SwapOutNet (VoidPtr med)
  836. {
  837.     return TRUE;
  838. }
  839.